use axum::{extract::Query, routing::{get, post}, Router};
use serde::Deserialize;

use crate::{error::AppErr, server::model::{cbor_ok, Cbor, CborRet, TypeIdReq, Verify, Void}, store::device::{self, TbDevice}};

#[derive(Debug, Deserialize)]
struct CreateReq {
    type_id: i64,
    mac_addr: String,
    name: String,
    remark: String,
}

async fn on_create(_v: Verify, req: Cbor<CreateReq>) -> Result<Void, AppErr> {
    device::create(req.type_id, &req.mac_addr, &req.name, &req.remark).await?;
    Ok(Void)
}

async fn on_query(req: Query<TypeIdReq>) -> CborRet<Box<[TbDevice]>> {
    let ds = device::query(req.type_id).await?;
    cbor_ok(ds)
}

async fn on_delete(_v: Verify, req: Cbor<i64>) -> Result<Void, AppErr> {
    device::delete(req.0).await?;
    Ok(Void)
}

#[derive(Debug, Deserialize)]
struct UpdateReq {
    id: i64,
    name: String,
    remark: String
}

async fn on_update(_v: Verify, req: Cbor<UpdateReq>) -> Result<Void, AppErr> {
    device::update(req.id, &req.name, &req.remark).await?;
    Ok(Void)
}

pub fn register() -> Router {
    Router::new()
        .route("/create", post(on_create))
        .route("/query", get(on_query))
        .route("/delete", post(on_delete))
        .route("/update", post(on_update))
}
